package cn.yaoud.salus.imexport.utils;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ZipUtil {

    private static final Integer DEFAULT_SIZE = 1024;
    private static final Integer END_FLAG = -1;
    private static final Integer ENIGHT = 8;

    /**
     * zip压缩文件
     * 
     * @param srcPath
     *            相对路径目录
     * @param zipFileName
     *            zip文件取名
     */
    public static void zipDirectory(String srcPath, String zipFileName) throws IOException {
        File file = new File(srcPath);
        String parent = file.getParent();
        File zipFile = new File(parent, zipFileName);
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
        zip(zos, file, file.getName());
        zos.flush();
        zos.close();
    }

    /**
     * @param zos
     *            压缩输出流
     * @param file
     *            当前需要压缩的文件
     * @param path
     *            当前文件相对于压缩文件夹的路径
     * @throws IOException
     */
    public static void zip(ZipOutputStream zos, File file, String path) throws IOException {
        // 首先判断是文件，还是文件夹，文件直接写入目录进入点，文件夹则遍历
        if (file.isDirectory()) {
            // 文件夹的目录进入点必须以名称分隔符结尾
            ZipEntry entry = new ZipEntry(path + File.separator);
            zos.putNextEntry(entry);
            File[] files = file.listFiles();
            for (File x : files) {
                zip(zos, x, path + File.separator + x.getName());
            }
        } else {
            FileInputStream fis = new FileInputStream(file);
            ZipEntry entry = new ZipEntry(path);
            zos.putNextEntry(entry);
            int len = 0;
            byte[] buf = new byte[DEFAULT_SIZE * ENIGHT];
            while ((len = fis.read(buf)) != END_FLAG) {
                zos.write(buf, 0, len);
            }
            zos.flush();
            fis.close();
            zos.closeEntry();
        }
    }

    /**
     * 删除同步文件
     */
    public static void deleteDir(String dirName) {
        System.gc();

        File file = new File(dirName);
        if (file.exists() && file.isDirectory()) {
            File[] files = file.listFiles();
            for (File temp : files) {
                temp.delete();
            }
            file.delete();
        }
        File zipFile = new File(dirName + ".zip");
        if (zipFile.exists()) {
            zipFile.delete();
        }
    }

    /**
     * 打包文件
     * 
     * @param file
     *            文件
     * @param out
     *            压缩输出流
     */
    public static void doCompress(File file, ZipOutputStream out) {
        try {
            String entryName = file.getName();
            ZipEntry entry = new ZipEntry(entryName);
            out.putNextEntry(entry);
            int length = 0;
            byte[] buffer = new byte[DEFAULT_SIZE];
            FileInputStream fis = new FileInputStream(file);
            while ((length = fis.read(buffer)) != END_FLAG) {
                out.write(buffer, 0, length);
                out.flush();
            }
            fis.close();
            out.closeEntry();
        } catch (Exception e) {
            log.error("打包文件异常{}", e.getMessage(), e);
        }
    }

    /**
     * @Author jiht
     * @Description 文件解压
     * @Date 2022/1/14 16:16
     * @Param [zipFile, outputPath]
     * @Return void
     **/
    public static void unzip(File zipFile, String outputPath) {
        if (outputPath == null) {
            outputPath = "";
        } else {
            outputPath += File.separator;
        }
        // 1.0 Create output directory
        File outputDirectory = new File(outputPath);

        if (outputDirectory.exists()) {
            outputDirectory.delete();
        }

        outputDirectory.mkdir();
        // 2.0 Unzip (create folders & copy files)
        try {
            // 2.1 Get zip input stream
            ZipInputStream zip = new ZipInputStream(new FileInputStream(zipFile));

            ZipEntry entry = null;
            int len;
            byte[] buffer = new byte[DEFAULT_SIZE];

            // 2.2 Go over each entry "file/folder" in zip file
            while ((entry = zip.getNextEntry()) != null) {
                if (!entry.isDirectory()) {
                    // create a new file
                    File file = new File(outputPath + entry.getName());

                    // create file parent directory if does not exist
                    if (!new File(file.getParent()).exists())
                        new File(file.getParent()).mkdirs();

                    // get new file output stream
                    FileOutputStream fos = new FileOutputStream(file);

                    // copy bytes
                    while ((len = zip.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    fos.close();
                }
            }
            zip.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
